from tiny_logger import TinyLogger
from visualization_tool import VisualizationTool
import pandas as pd
from loguru import logger
from line_processor import LineProcessor

class SmapsSumAnalyzer(LineProcessor):
    """smaps summary文件解析工具

    hidumper --mem 输出的文件
    """
    focus = ["GL", "Graph", "ark ts heap", "guard", "native heap", "AnonPage other", "stack", ".hap", ".so",
             ".ttf", "dev", "FilePage other", "Total",
             "jemalloc meta:", "jemalloc heap:", "brk heap:", "musl heap:"]
    ignore = ["native heap:"]
        

    def __init__(self, cfg):
        TinyLogger("DEBUG")
        self.file = cfg["file"]
        self.pic_path = cfg["pic"]
        self.pic_cols = cfg["pic_cols"]
        self.vt = VisualizationTool()
        self.data = self.init_data()

    def init_data(self):
        data = {}
        for key in self.focus:
            data[key] = []
        return data

    def add_seg(self, seg):
        for key, val in seg.items():
            if key in self.data:
                self.data[key].append(val)
            else:
                logger.error(f"{key} not in {self.data}")

    def get_first_val(self, key, line: str):
        """
            GL             0  -> 0
        """
        start = line.index(key) + len(key)
        return int(line[start:].split()[0])

    def skip(self, line) -> bool:
        for key in self.ignore:
            if key in line:
                return True
        if "Total" in line and "Clean" in line:
            return True
        return False
    
    def header(self, line):
        return "[memory]" in line

    def line_to_val(self, line: str):
        for key in self.focus:
            if key in line:
                return {"key": key, "value": self.get_first_val(key, line)}
        return None

    def update_seg_body(self, seg: dict, part) -> dict:
        seg[part["key"]] = part["value"]

    def run(self):
        result = self.process(self.file)
        # logger.info(f"{result}")
        for seg in result:
            self.add_seg(seg)

        self.plot()
        logger.debug("smaps summary analyzer run success!")
    
    def plot(self):
        self.vt.update_cfg({
            "figure_size": (12, 12),
            "path": self.pic_path,
            "title": "Test Plot",
            "xlabel": "index",
            "ylabel": "Mem(kB)",
            "interval": 5,
        })
        self.vt.line(pd.DataFrame(self.data)[self.pic_cols])

    

if __name__ == "__main__":
    ssa = SmapsSumAnalyzer({
        "file": "in/mem_sum_00.txt",
        "pic": "out/out.png",
        "pic_cols": ["Total", "native heap"]
    })
    ssa.run()
